package com.cyx.spring.tx;

import javax.sql.DataSource;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * DataSourceTransactionManager
 *
 * @author yongxiang
 * @date 2024/10/25 14:16
 * @desc
 */

public class DataSourceTransactionManager implements PlatformTransactionManager, InvocationHandler {

    public static final ThreadLocal<TransactionStatus> statusThreadLocal = new ThreadLocal<>();

    private DataSource dataSource;

    public DataSourceTransactionManager(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //首先判断是否是
        TransactionStatus transactionStatus = statusThreadLocal.get();
        if (transactionStatus == null){
            //需要获取连接
            Connection connection = null;
            boolean autoCommit = false;
            try{
                connection  = dataSource.getConnection();
                connection.setAutoCommit(false);
                autoCommit = connection.getAutoCommit();
                if (autoCommit) {
                    connection.setAutoCommit(false);
                }
                statusThreadLocal.set(new TransactionStatus(connection));
                //执行方法
                Object res  = method.invoke(proxy,args);
                connection.commit();
                return res;
            }catch (Exception exception){
                //回滚事务
                connection.rollback();
                throw new RuntimeException("事务执行失败。。。"+method,exception);
            }finally {
                statusThreadLocal.remove();
                if (connection != null){
                    connection.close();
                }
                if (autoCommit) {
                    connection.setAutoCommit(true);
                }
            }
        }else {
            return method.invoke(proxy,args);
        }
    }
}
